<?php

namespace PhpQq\WebQq;

class MessageQueue {

    private static $instance;
    private $inbox;
    
    /**
     * 个人消息处理方法
     * @var type 
     */
    private $messageExec = [];
    
    /**
     * 群消息处理方法
     * @var type 
     */
    private $messageGoupExec;
    private $outbox;

    private function __construct() {
        self::$instance = $this;
        $this->inbox = new \Threaded;
        $this->outbox = new \Threaded;
    }

    public static function getInstance() {
        if (!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * @return Message|bool
     */
    public function getMessage() {
        if (count($this->inbox) > 0) {
            $msg = $this->inbox->shift();
            return (new Message())->receive($msg);
        }
        return false;
    }

    public function sendMessage(Message $message) {
        $message = serialize([
            'type' => $message->getType(),
            'target' => $message->getTarget()->getUin(),
            'content' => $message->getContent()
        ]);
        $this->outbox[] = $message;
    }

    public function getOutbox() {
        return $this->outbox;
    }

    public function getInbox() {
        return $this->inbox;
    }
    
    /**
     * 消息处理的方法
     * @return type
     */
    public function messageExec() {
        return $this->messageExec;
    }
    
    /**
     * 注册消息处理的方法
     * @param string $execName
     * @param string $messageType
     * @param \PhpQq\WebQq\WebQqMessageExec $messageExec
     * @throws Exception
     * @rerturn boolean or  string
     * 返回true 就停止执行下面的方法 返回字符串就是回复的消息  返回false的话 就不执行
     */
    public function setMessageExec($execName,$messageType,WebQqMessageExec $messageExec) {
        if(!isset($this->messageExec[$messageType]))
        {
            $this->messageExec[$messageType] = [];
        }
        
        if(isset($this->messageExec[$messageType][$execName]))
        {
            throw new Exception($execName.' already exists');
        }
        
        $this->messageExec[$messageType][$execName] = $messageExec;
        
    }
    

}
